﻿using System;
using System.Linq;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Windows.Forms;
using PefStudio.Services;

namespace PefStudio.StartUp
{
    class Program
    {
        [STAThread]
        static void Main()
        {
#if (DEBUG)
            RunInDebugMode();
#else
            RunInReleaseMode();
#endif
        }

        private static void Compose()
        {
            var catalog = new AggregateCatalog();
            catalog.Catalogs.Add(new DirectoryCatalog("."));

            var container = new CompositionContainer(catalog);
            container.ComposeParts();

            var bootstrappers = container.GetExportedValues<Bootstrapper>(Bootstrapper.Contract);
            Bootstrapper selectedBootstrapper = null;
            if (bootstrappers.Count() > 1)
            {
                var form = new SelectBootstrapperForm {Bootstrappers = bootstrappers};
                if (form.ShowDialog() == DialogResult.OK)
                    selectedBootstrapper = form.SelectedBootstrapper;
            }
            else
                selectedBootstrapper = bootstrappers.First();

            var loggingServices = container.GetExportedValues<ILoggingService>(LoggingService.Contract);
            var selectedLoggingService = loggingServices.Count() > 0 ? loggingServices.First() : new TextWriterLoggingService();
            if (selectedLoggingService != null) LoggingService.Instance.ILoggingService = selectedLoggingService;

            LoggingService.Info("Starting PefStudio...");

            var messageServices = container.GetExportedValues<IMessageService>(MessageService.Contract);
            var selectedMessageService = messageServices.Count() > 0 ? messageServices.First() : new TextWriterMessageService();
            if (selectedMessageService != null) MessageService.Instance.IMessageService = selectedMessageService;

            if(selectedBootstrapper != null)
                selectedBootstrapper.Run(true);
        }

        private static void RunInDebugMode()
        {
            Compose();
        }

        private static void RunInReleaseMode()
        {
            AppDomain.CurrentDomain.UnhandledException += AppDomainUnhandledException;
            try
            {
                Compose();
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
        }

        private static void AppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            HandleException(e.ExceptionObject as Exception);
        }

        private static void HandleException(Exception ex)
        {
            if (ex == null)
                return;

            //ExceptionPolicy.HandleException(ex, "Default Policy");
            //MessageBox.Show(StockTraderRI.Properties.Resources.UnhandledException);
            MessageBox.Show(ex.Message);
            Environment.Exit(1);
        }
    }
}
